# ======================================================================
#
# Copyright (C) ADN
# ADN::LIBRARY::TFTP::ServerTFTP ServerTFTP.pm
# Description:
#  - Serveur TFTP
#  - TFTP server
#
# ======================================================================

package ADN::LIBRARY::TFTP::ServerTFTP;

use strict;
use Net::TFTPd;
use ADN::CONF::Read;
use ADN::LOG::Log;
use ADN::LANG::Lang;

# #######################
# CREATE OBJECT
# #######################
sub new
{
	# Construction de l'objet $self
	my $self = shift;
	my $class = ref($self) || $self;
	return $self if ref $self;
	$self = bless {} => $class;
  $self->{log} = ADN::LOG::Log->new();
  %{$self->{lang}} = ADN::LANG::Lang->new()->tftp();
  $self->_init();
	return $self;
}

# #######################
# Fonction initialisation
# #######################
sub _init
{
	my $self = shift;
  # Chargement du fichier de configuration XML + Initialisation variable.
  my $conf = ADN::CONF::Read->new();
  ($conf =~ m/^[-]1$/smx) ? ($self->{error} = 1) : ();
  if ($self->{error} != 1)
  {
    my %TFTP = $conf->TFTP();
    ($conf->TFTP() =~ m/^[-]1$/smx) ? ($self->{error} = 1) : ();

    $self->{timeout} = $TFTP{timeout};
	  $self->{acktimeout} = $TFTP{acktimeout};
    $self->{ackretries} = $TFTP{ackretries};
	  $self->{localport} = $TFTP{localport};
    $self->{rootdir} = $TFTP{rootdir};
	  $self->{readable} = $TFTP{readable};
    $self->{writable} = $TFTP{writable};
	  $self->{blksize} = $TFTP{blksize};
	  $self->{address} = $TFTP{address};
	  $self->{path_inc} = $conf->_send_path();
	  undef $conf;
  }
  return;
}

# #######################
# START
# #######################
sub start
{
  my $self = shift;

  if (defined($_[0]) && ($_[0] =~ /^[0-9]*$/smx)) {
    $self->{timeout} = $_[0];
  }

  if (!defined($self->{tftp})) {

    $self->{tftp} = Net::TFTPd->new(
                                  'RootDir'     =>  $self->{path_inc}.$self->{rootdir},
                                  'LocalPort'   =>  $self->{localport},
                                  'Timeout'     =>  $self->{timeout},
                                  'ACKtimeout'  =>  $self->{acktimeout},
                                  'ACKretries'  =>  $self->{ackretries},
                                  'Readable'    =>  $self->{readable},
                                  'Writable'    =>  $self->{writable},
                                  'BlkSize'     =>  $self->{blksize}
                                ) or $self->{log}->Log( $self->{lang}{mess1}.Net::TFTPd->error, 3, 5 );

    if (!defined(Net::TFTPd->error)) {
      $self->{log}->Log( $self->{lang}{mess4}, 1, 5 );
    }
  }
  return (1);
}

# #######################
# PROCESS
# #######################
sub _process
{
  my $self = shift;

  $self->{tftpRQ} = $self->{tftp}->waitRQ() or $self->{log}->Log( $self->{lang}{mess2}.Net::TFTPd->error, 3, 5 );

  $self->{log}->Log( $self->{lang}{mess5}, 1, 5 );

  $self->{tftpRQ}->processRQ();
  $self->{log}->Log( $self->{lang}{mess3}.$self->{tftpRQ}->getTotalBytes() || 0, 1, 5 );
  $self->{log}->Log( $self->{lang}{mess6}.$self->{tftpRQ}->getFileName(), 1, 5 );
  return (1);
}

# #######################
# PATH TFTP
# #######################
sub address_tftp
{
  my $self = shift;

  return ($self->{address});
}

# #######################
# ADDRESS TFTP
# #######################
sub path_tftp
{
  my $self = shift;

  return ($self->{path_inc}.$self->{rootdir});
}

# #######################
# BOUCLE SEND
# #######################
sub boucle_send
{
  my $self = shift;
  my ($line, $return);

  if (defined($_[0]) && defined($_[1])) {
    while (1) {
      $self->_process();
      $line = $_[0]->get_lastline(1);
      if ($line =~ /$_[1]/smx) {
				$return = "0";
				last;
			}
			elsif ($line !~ /$_[1]/smx) {
        $return = "-1";
			}
    }
  }
  undef($line);
	return $return;
}

# #######################
# DESTROY OBJECT
# #######################
sub DESTROY {
    my $self = shift;
    return;
}
1;
__END__
